package cn.est.controller;

import cn.est.constants.Constants;
import cn.est.dto.Result;
import cn.est.pojo.Users;
import cn.est.service.SmsLogService;
import cn.est.service.TokenService;
import cn.est.service.UsersService;
import cn.est.utils.*;
import cn.est.vo.TokenVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.management.ValueExp;
import java.util.UUID;

@Api("user")
@RestController
@RequestMapping("/api/")
public class LoginController {

    @Autowired
    RedisUtil redisUtil;

    @Autowired
    SmsLogService smsLogService;

    @Autowired
    UsersService usersService;

    @Autowired
    TokenService tokenService;

    @ApiOperation(value = "发送短信验证码接口",produces="application/json",notes ="发送短信")
    @ApiImplicitParams({
            @ApiImplicitParam(name="phone",value = "手机号码",required = true,dataType = "string"),
            @ApiImplicitParam(name="codeType",value = "验证码类型，0注册 1 修改密码 2通知，下单通知",required = true,dataType = "string")
    })
    @PostMapping("/sms/verfycode")
    public Result verifyCode(String phone,Integer codeType) {
        //1.判断手机号码是否正确
        if(!checkPhone(phone)){
            return ResultUtils.returnFail("手机号码错误","200001");
        }
        //2.判断手机验证码是否正确
        if(!checkCodeType(codeType.toString())){
            return ResultUtils.returnFail("手机验证码错误","200002");
        }
        //3.验证码发送的频率
        if(!checksmsCode(phone,codeType)){
            return ResultUtils.returnFail("太频繁发送短信验证码了","200003");
        }
        //4.发送短信
        try {
            smsLogService.sendMessage(phone,codeType);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtils.returnFail("发送短信系统异常");
        }
        return ResultUtils.returnSuccess();
    }

    @ApiOperation(value = "手机验证码注册或登录接口",produces="application/json",notes ="手机验证码注册或登录接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name="phone",value = "手机号码",required = true,dataType = "string"),
            @ApiImplicitParam(name="sms",value = "手机输入的验证码",required = true,dataType = "string")
    })
    @PostMapping("/user/login/sms")
    public Result login(@RequestParam("phone")String phone,@RequestParam("sms")String sms){
        //1.验证手机号码是否正确
        if(!checkPhone(phone)){
            return ResultUtils.returnFail("手机号码错误","200001");
        }
        //2.效验验证码是否存在在redis中
        String key=Constants.Redis.PREFIX_SMS+"0"+":"+phone;
        String keyvalue= (String) redisUtil.get(key);
        if(keyvalue==null||!keyvalue.equals(sms)){
            return  ResultUtils.returnFail("验证码有误，请从新输入","2004");
        }
        //3.实现登录功能
        TokenVo tokenVo=null;
        try {
            Users users=usersService.loginByPhone(phone);
            //4.生成系统令牌
            tokenVo=tokenService.genenrateToken(users);
            //5.保存到redis中
            tokenService.saveToken(tokenVo.getToken(),users);
        } catch (EstSQLException e) {
            e.printStackTrace();
            return ResultUtils.returnFail("数据库异常，注册失败","20005");
        }
        return ResultUtils.returnDataSuccess(tokenVo);
    }




    private  boolean checkPhone(String phone){
        boolean flag=false;
        if(!StringUtils.isBlank(phone)){
            //手机号码不为空，正则表达式
            flag=phone.matches(Constants.PHONE_REGSTR);
        }
        return flag;
    }

    private boolean checkCodeType(String codeType){
        boolean flag=false;
        if(codeType!=null){
            if(codeType.equals("0")||codeType.equals("1")||codeType.equals("2")){
                flag=true;
            }
        }
        return flag;
    }

    private boolean checksmsCode(String phone,Integer codeType){
        String key =Constants.Redis.PREFIX_SMS+codeType+":"+phone;

        //4.把验证码放在redis中、
        String code= (String) redisUtil.get(key);
        if(code!=null){
            return  false;
        }
        return true;
    }


}
